<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>HTML DOM - Zoom an image</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="/css/demo.css" />
        <link rel="preconnect" href="https://fonts.gstatic.com" />
        <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css2?family=Inter&family=Source+Code+Pro&display=swap"
        />
        <style>
            .image-container {
                /* Center the image */
                align-items: center;
                display: flex;
                justify-content: center;

                /* Misc */
                border: 1px solid #cbd5e0;
                overflow: hidden;
                width: 100%;
            }
            .range-wrapper {
                /* Center the content */
                align-items: center;
                display: flex;
                justify-content: center;

                /* Misc */
                padding-top: 2rem;
            }
            .range-container {
                /* Content is centered horizontally */
                align-items: center;
                display: flex;

                /* Size */
                height: 1.5rem;
                width: 16rem;

                /* Misc */
                margin: 0 0.25rem;
            }
            .left {
                /* Width based on the current value */
                height: 2px;

                /* Colors */
                background-color: rgba(0, 0, 0, 0.3);
            }
            .knob {
                /* Size */
                height: 1.5rem;
                width: 1.5rem;

                /* Rounded border */
                border-radius: 9999px;

                /* Colors */
                background-color: rgba(0, 0, 0, 0.3);
                cursor: pointer;
            }
            .right {
                /* Take the remaining width */
                flex: 1;
                height: 2px;

                /* Colors */
                background-color: rgba(0, 0, 0, 0.3);
            }
        </style>
    </head>
    <body>
        <div class="image-container">
            <img id="image" src="/assets/city.jpg" />
        </div>

        <div class="range-wrapper">
            <div class="select-none">10%</div>
            <div class="range-container">
                <div class="left"></div>
                <div class="knob" id="knob"></div>
                <div class="right"></div>
            </div>
            <div class="select-none">200%</div>
        </div>

        <script>
            document.addEventListener('DOMContentLoaded', function () {
                // Query the elements
                const image = document.getElementById('image');
                const knob = document.getElementById('knob');
                const leftSide = knob.previousElementSibling;
                const rightSide = knob.nextElementSibling;

                // The current position of mouse
                let x = 0;
                let y = 0;
                let leftWidth = 0;

                const minScale = 0.1;
                const maxScale = 2;
                const step = (maxScale - minScale) / 100;

                // Create new image element
                const cloneImage = new Image();
                cloneImage.addEventListener('load', function (e) {
                    // Get the natural size
                    const width = e.target.naturalWidth;
                    const height = e.target.naturalHeight;

                    // Set the size for image
                    image.style.width = `${width}px`;
                    image.style.height = `${height}px`;

                    const scale = image.parentNode.getBoundingClientRect().width / width;
                    image.style.transform = `scale(${scale}, ${scale})`;

                    leftSide.style.width = `${(scale - minScale) / step}%`;
                });
                // Clone it
                cloneImage.src = image.src;

                // Handle the mousedown event
                // that's triggered when user drags the knob
                const mouseDownHandler = function (e) {
                    // Get the current mouse position
                    x = e.clientX;
                    y = e.clientY;
                    leftWidth = leftSide.getBoundingClientRect().width;

                    // Attach the listeners to `document`
                    document.addEventListener('mousemove', mouseMoveHandler);
                    document.addEventListener('mouseup', mouseUpHandler);
                };

                const mouseMoveHandler = function (e) {
                    // How far the mouse has been moved
                    const dx = e.clientX - x;
                    const dy = e.clientY - y;

                    const containerWidth = knob.parentNode.getBoundingClientRect().width;
                    let newLeftWidth = ((leftWidth + dx) * 100) / containerWidth;
                    newLeftWidth = Math.max(newLeftWidth, 0);
                    newLeftWidth = Math.min(newLeftWidth, 100);

                    leftSide.style.width = `${newLeftWidth}%`;

                    leftSide.style.userSelect = 'none';
                    leftSide.style.pointerEvents = 'none';

                    rightSide.style.userSelect = 'none';
                    rightSide.style.pointerEvents = 'none';

                    const scale = minScale + newLeftWidth * step;
                    image.style.transform = `scale(${scale}, ${scale})`;
                };

                // Triggered when user drops the knob
                const mouseUpHandler = function () {
                    leftSide.style.removeProperty('user-select');
                    leftSide.style.removeProperty('pointer-events');

                    rightSide.style.removeProperty('user-select');
                    rightSide.style.removeProperty('pointer-events');

                    // Remove the handlers of `mousemove` and `mouseup`
                    document.removeEventListener('mousemove', mouseMoveHandler);
                    document.removeEventListener('mouseup', mouseUpHandler);
                };

                // Attach the handler
                knob.addEventListener('mousedown', mouseDownHandler);
            });
        </script>
    </body>
</html>
